<?php
define('CLIENT_MULTI_RESULTS', 131072);
class DbMysql extends Db implements IDb {
	protected function __construct() {
		if ( !extension_loaded('mysql') ) {
            throwException('NOT SUPPERT:mysql');
        }
	}
	
	/**
	 * 连接数据库
	 */
	public function connect($config=array(),$linkNum=0, $read=true) {
		$linkNum = ($read ? 'r' : 'w') . $linkNum;
        if ( !isset($this->linkID[$linkNum]) ) {
            if(empty($config))  $config =   $this->config;
            // 处理不带端口号的socket连接情况
            $host = $config[0].($config[1]?":{$config[1]}":'');
            if($this->cfg['db_pconnect']) {
                $this->linkID[$linkNum] = mysql_pconnect( $host, $config[2], $config[3],CLIENT_MULTI_RESULTS);
            }else{
                $this->linkID[$linkNum] = mysql_connect( $host, $config[2], $config[3],true,CLIENT_MULTI_RESULTS);
            }
            if ( !$this->linkID[$linkNum] || ('' != $this->cfg['db_name'] && !mysql_select_db($this->cfg['db_name'], $this->linkID[$linkNum])) ) {
                throwException(mysql_error());
            }
            $dbVersion = mysql_get_server_info($this->linkID[$linkNum]);
            if ($dbVersion >= "4.1") {
                //使用UTF8存取数据库 需要mysql 4.1.0以上支持
				if (function_exists('mysql_set_charset')) {
					//mysql_set_charset较“SET NAMES”安全。
					@mysql_set_charset($this->cfg['db_charset'], $this->linkID[$linkNum]);
				} else {
                	mysql_query("SET NAMES '".$this->cfg['db_charset']."'", $this->linkID[$linkNum]);
				}
				//设置时区
				mysql_query("SET GLOBAL time_zone = '".$this->cfg['db_timezone']."'", $this->linkID[$linkNum]);
            }
            //设置 sql_model
            if($dbVersion >'5.0.1'){
                mysql_query("SET sql_mode=''",$this->linkID[$linkNum]);
            }
            // 标记连接成功
            $this->connected    =   true;
        }
        return $this->linkID[$linkNum];
    }
	
	/**
	 * 读取
	 */
	public function query($str) {
        $this->initConnect();
        if ( !$this->_linkID ) return false;
        $this->queryStr = $str;
        //释放前次的查询结果
        if ( $this->queryID ) {    $this->free();    }
        $this->Q(1);
        $this->queryID = mysql_query($str, $this->_linkID);
        $this->debug();
        if ( false === $this->queryID ) {
            $this->error();
            return false;
        } else {
            $this->numRows = mysql_num_rows($this->queryID);
            return $this->getAll();
        }
    }
	
	/**
	 * 写入
	 */
	public function execute($str) {
        $this->initConnect(false);
        if ( !$this->_linkID ) return false;
        $this->queryStr = $str;
        //释放前次的查询结果
        if ( $this->queryID ) {    $this->free();    }
        $this->W(1);
        $result =   mysql_query($str, $this->_linkID) ;
        $this->debug();
        if ( false === $result) {
            $this->error();
            return false;
        } else {
            $this->numRows = mysql_affected_rows($this->_linkID);
            $this->lastInsID = mysql_insert_id($this->_linkID);
            return $this->numRows;
        }
    }
	
	/**
	 * 转义数据，仅写入需要
	 */
	public function escape_string($str) {
		$this->initConnect(false);
		if(function_exists('mysql_real_escape_string')) {
			return mysql_real_escape_string($str, $this->_linkID);
		} elseif(function_exists('mysql_escape_string')) {
			return mysql_escape_string($str);
		} else {
			return addslashes($str);
		}
    }
	
	/**
	 * 只有写入才启动事务
	 */
	public function startTrans() {
        $this->initConnect(false);
        if ( !$this->_linkID ) return false;
        //数据rollback 支持
        if ($this->transTimes == 0) {
            mysql_query('START TRANSACTION', $this->_linkID);
        }
        $this->transTimes++;
        return ;
    }
	
	public function commit()
    {
		$this->initConnect(false);
        if ($this->transTimes > 0) {
            $result = mysql_query('COMMIT', $this->_linkID);
            $this->transTimes = 0;
            if(!$result){
                throwException($this->error());
            }
        }
        return true;
    }
	
	public function rollback()
    {
		$this->initConnect(false);
        if ($this->transTimes > 0) {
            $result = mysql_query('ROLLBACK', $this->_linkID);
            $this->transTimes = 0;
            if(!$result){
                throwException($this->error());
            }
        }
        return true;
    }
	
	public function close() {
        if (!empty($this->queryID))
            //mysql_free_result($this->queryID);
			$this->free();
        if ($this->_linkID && !mysql_close($this->_linkID)){
            throwException($this->error());
        }
        $this->_linkID = 0;
    }
	
	public function error() {
        $this->error = mysql_error($this->_linkID);
        if($this->cfg['db_debug'] && '' != $this->queryStr){
            $this->error .= "\n [ SQL语句 ] : ".$this->queryStr;
        }
        return $this->error;
    }
	
	private function free() {
        @mysql_free_result($this->queryID);
        $this->queryID = 0;
    }
	
	private function getAll() {
        //返回数据集
        $result = array();
        if($this->numRows >0) {
            while($row = mysql_fetch_assoc($this->queryID)){
                $result[]   =   $row;
            }
            mysql_data_seek($this->queryID,0);
        }
        return $result;
    }
	
	/**
	 * 获取数据表的字段信息
	 */
	public function getFields($tableName) {
        $result =   $this->query('SHOW COLUMNS FROM '.$tableName);
        $info   =   array();
        if($result) {
            foreach ($result as $key => $val) {
                $info[$val['Field']] = array(
                    'name'    => $val['Field'],
                    'type'    => $val['Type'],
                    'notnull' => (bool) ($val['Null'] === ''), // not null is empty, null is yes
                    'default' => $val['Default'],
                    'primary' => (strtolower($val['Key']) == 'pri'),
                    'autoinc' => (strtolower($val['Extra']) == 'auto_increment'),
                );
            }
        }
        return $info;
    }
	
	/**
	 * 取得数据库的表信息
	 */
	public function getTables($dbName='') {
        if(!empty($dbName)) {
           $sql    = 'SHOW TABLES FROM '.$dbName;
        }else{
           $sql    = 'SHOW TABLES ';
        }
        $result =   $this->query($sql);
        $info   =   array();
        foreach ($result as $key => $val) {
            $info[$key] = current($val);
        }
        return $info;
    }
	
	/**
	 * 替换记录
	 */
	public function replace($data,$options=array()) {
        foreach ($data as $key=>$val){
            $value   =  $this->parseValue($val);
            if(is_scalar($value)) { // 过滤非标量数据
                $values[]   =  $value;
                $fields[]     =  $this->addSpecialChar($key);
            }
        }
        $sql   =  'REPLACE INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')';
        return $this->execute($sql);
    }
	
	/**
	 * 插入记录
	 */
	public function insertAll($datas,$options=array()) {
        if(!is_array($datas[0])) return false;
        $fields = array_keys($datas[0]);
        array_walk($fields, array($this, 'addSpecialChar'));
        $values  =  array();
        foreach ($datas as $data){
            $value   =  array();
            foreach ($data as $key=>$val){
                $val   =  $this->parseValue($val);
                if(is_scalar($val)) { // 过滤非标量数据
                    $value[]   =  $val;
                }
            }
            $values[]    = '('.implode(',', $value).')';
        }
        $sql   =  'INSERT INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values);
        return $this->execute($sql);
    }
	
	public function __destruct()
    {
        // 关闭连接
        $this->close();
    }
}